
#include "render_galaxy.h"


RenderGalaxy::RenderGalaxy()
{

}

RenderGalaxy::~RenderGalaxy()
{

}

void		RenderGalaxy::init(Galaxy *galaxy)
{
  this->galaxy = galaxy;
  this->resetTransform();
  this->pickingMode = PICKING_MODE_OFF;

  this->sysToPrint = NO_SYS_TO_DISPLAY;
}

void		RenderGalaxy::render()
{
  int		galaxySize;
  SolarSystem	*solarSystem;
  int		i;
  int		pointSize;
  int		objHit;

  // std::cout << "enter render" << std::endl;

  // Clear the window with current clearing color
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();
  if(this->pickingMode == PICKING_MODE_ON)
    this->startPicking(this->xToPick, this->yToPick);

  //glMatrixMode(GL_MODELVIEW);

  // Save matrix state and do the rotation
  glPushMatrix();

  //glTranslatef(0.0f, 0.0f, -600.0f);
  glTranslatef(0.0f, 0.0f, -600.0f);



  glRotatef(this->xrot, 1.0f, 0.0f, 0.0f);
  glRotatef(this->yrot, 0.0f, 1.0f, 0.0f);
  // zoom
  glScalef(1.0f + this->zoom, 1.0f + this->zoom, 1.0f + this->zoom);

  glShadeModel(GL_SMOOTH);

  // naming objects init


  glInitNames();
  glPushName(0);

  //glPushMatrix();
  for(i = 0, galaxySize = galaxy->getGalaxySize();
      i < galaxySize; i++)
    {
      //    std::cout << "start picking " << i <<std::endl;
      solarSystem = galaxy->getSolarSystem(i);


      // color switch
      switch(solarSystem->getSolColor())
	{
	case SOL_SYS_COLOR_RED:
	  glColor3f(1.0f, 0.0f, 0.0f);
	  break;
	case SOL_SYS_COLOR_YELLOW:
	  glColor3f(0.937f, 0.898f, 0.546f);
	  break;
	case SOL_SYS_COLOR_WHITE:
	  glColor3f(1.0f, 1.0f, 1.0f);
	  break;
	case  SOL_SYS_COLOR_BLUE:
	  glColor3f(0.117f, 0.562f, 1.0f);
	  break;
	}

      switch(solarSystem->getSolType())
	{
	case SOL_SYS_BIG:
	  pointSize = SOL_SYS_BIG_SIZE;
	  break;
	case SOL_SYS_MEDIUM:
	  pointSize = SOL_SYS_MID_SIZE;
	  break;
	case SOL_SYS_SMALL:
	  pointSize = SOL_SYS_SMA_SIZE;
	  break;
	}
      glPointSize(pointSize);

      glLoadName(solarSystem->getSolSysId() + 1);

      glBegin(GL_POINTS);
      glVertex3f(solarSystem->getXcoord(),
		 solarSystem->getYcoord(),
		 solarSystem->getZcoord());
      glEnd();
    }

  glColor3f(1.0f, 0.0f, 1.0f);
  glPopMatrix();

  if(pickingMode == PICKING_MODE_ON)
    {
      if((objHit = this->stopPicking(1)) > 0)
	this->sysToPrint = objHit - 1;
    }
  else
    {
      if(sysToPrint != NO_SYS_TO_DISPLAY)
	{
	  printPlaneteInfo(xToPick + GALAXY_TEXT_RIGHT_SPACE
			   , glutGet(GLUT_WINDOW_HEIGHT) - yToPick - GALAXY_TEXT_DOWN_SPACE
			   , galaxy->getSolarSystem(sysToPrint));
	  
 	}
      glutSwapBuffers();
    }
}

void		RenderGalaxy::printPlaneteInfo(int x, int y, SolarSystem *system)
{
  std::string	stringToPrint;
  char		*tmpVal;

  if(system->getSolName().size() == 0)
    stringToPrint += "UNKNOW";
  else
    stringToPrint += system->getSolName();

  stringToPrint += "\n";
  switch(system->getSolColor())
    {
    case SOL_SYS_COLOR_RED:
      stringToPrint += SOL_SYS_COLOR_RED_STR;
      break;
    case SOL_SYS_COLOR_YELLOW:
      stringToPrint += SOL_SYS_COLOR_YEL_STR;
      break;
    case SOL_SYS_COLOR_WHITE:
      stringToPrint += SOL_SYS_COLOR_WHI_STR;
      break;
    case  SOL_SYS_COLOR_BLUE:
      stringToPrint += SOL_SYS_COLOR_BLU_STR;
      break;
    }
  stringToPrint += " ";
  switch(system->getSolType())
    {
    case SOL_SYS_BIG:
      stringToPrint += SOL_SYS_SIZE_BIG_STR;
      break;
    case SOL_SYS_MEDIUM:
      stringToPrint += SOL_SYS_SIZE_MID_STR;
      break;
    case SOL_SYS_SMALL:
      stringToPrint += SOL_SYS_SIZE_SMA_STR;
      break;
    }
  tmpVal = (char*)stringToPrint.c_str();
  this->printText(x, y, tmpVal, (float)1.0f, (float)1.0f, (float)1.0f);
}

void		RenderGalaxy::xRot(GLfloat xRot)
{
  this->xrot += xRot;
}

void		RenderGalaxy::yRot(GLfloat yRot)
{
  this->yrot += yRot;
}

void		RenderGalaxy::zoomChange(GLfloat zoom)
{
  this->zoom += zoom;
  if(this->zoom < -0.4)
    this->zoom = -0.4;
  if(this->zoom > 0.8)
    this->zoom = 0.8;
}

void		RenderGalaxy::resetTransform()
{
  this->xrot = 0.0f;
  this->yrot = 0.0f;
  this->zoom = -0.2f;
}

void		RenderGalaxy::normalKeyEvent(unsigned char key, int x, int y)
{
  switch(key)
    {
    case 32: // space
      this->resetTransform();
      break;
    case 27: // echap
      exit(EXIT_SUCCESS);
      break;
    case 113: // q
      exit(EXIT_SUCCESS);
      break;
    default:
      std::cout << "unknow key press : " << (int)key << std::endl;
      break;
    }
  glutPostRedisplay();
}

void		RenderGalaxy::specialKeyEvent(int key, int x, int y)
{
  switch(key)
    {
    case 101: // key up
      this->xRot(-5.0f);
      break;
    case 103: // key down
      this->xRot(5.0f);
      break;
    case 100: // key left
      this->yRot(-5.0f);
      break;
    case 102: // key right
      this->yRot(5.0f);
      break;
    case 104: // page up
      this->zoomChange(0.1f);
      break;
    case 105: // page down
      this->zoomChange(-0.1f);
      break;
    default:
      std::cout << "unknow key press : " << (int)key << std::endl;
      break;
    }

  // Refresh the Window
  glutPostRedisplay();
}

void		RenderGalaxy::mouseEvent(int button, int state, int x, int y)
{
  // specialKey = glutGetModifiers();
//   // if both a mouse button, and the ALT key, are pressed  then
//   if ((state == GLUT_DOWN) &&
//       (specialKey == GLUT_ACTIVE_ALT)) {

//     // set the color to pure red for the left button
//     if (button == GLUT_LEFT_BUTTON) {
//       red = 1.0; green = 0.0; blue = 0.0;
//     }
//     // set the color to pure green for the middle button
//     else if (button == GLUT_MIDDLE_BUTTON) {
//       red = 0.0; green = 1.0; blue = 0.0;
//     }
//     // set the color to pure blue for the right button
//     else {
//       red = 0.0; green = 0.0; blue = 1.0;
//     }
//   }

  std::cout << "Mouse envent button: " << button
	    << " state: " << state
	    << " x: " << x
	    << " y: " << y << std::endl;
}

void		RenderGalaxy::mousePassiveMotion(int x, int y)
{
  this->pickingMode = PICKING_MODE_ON;
  this->xToPick = x;
  this->yToPick = y;

  this->render();
  this->render();
  this->sysToPrint = NO_SYS_TO_DISPLAY;
}

// void		RenderGalaxy::processHits(GLint hits, GLuint buffer[])
// {
//   int		i;
//   GLuint	names, *ptr, minZ,*ptrNames, numberOfNames;

//   ptr = (GLuint *) buffer;
//   minZ = 0xffffffff;
//   for (i = 0; i < hits; i++) {
//     names = *ptr;
//     ptr++;
//     if (*ptr < minZ) {
//       numberOfNames = names;
//       minZ = *ptr;
//       ptrNames = ptr+2;
//     }

//     ptr += names+2;
//   }

//   ptr = ptrNames;
//   this->sysToPrint = *ptr - 1;

//}
